package tinking.java.operator.example;

import java.util.LinkedList;
import java.util.List;

/**
 * @author GaoFeng
 * @date 2019/12/26 19:35
 */
public class Ex_3_11_work {

    public static void main(String[] args) {
        // practice11(-1);
        // practice12(-1);
        // String s = practice13(1000);
        // System.out.println(s);
        // System.out.println(Long.toBinaryString(Long.MIN_VALUE));
        // System.out.println(removeEqualsBit(10, 2));
        // System.out.println(bits(10));
        // leftMove(1);
        bitTest();
    }

    private static void bitTest() {

        // 初始化权限为1000
        int ownBit = 1000;

        // 判断是否拥有权限512
        System.out.println(isInclude(ownBit, 512));

        // 判断是否拥有权限1
        System.out.println(isInclude(ownBit, 1));

        // 删除权限512
        ownBit = removeEqualsBit(ownBit, 512);
        System.out.println("deduct 512 -> " + ownBit);

        // 删除权限128
        ownBit = removeEqualsBit(ownBit, 128);
        System.out.println("deduct 128 -> " + ownBit);

        // 判断是否拥有权限512
        System.out.println(isInclude(ownBit, 512));

        // 增加相同的权限
        ownBit = addUnequalsBit(ownBit, ownBit);
        System.out.println("add self -> " + ownBit);

        // 增加权限1024
        ownBit = addUnequalsBit(ownBit, 1024);
        System.out.println("add 1024 -> " + ownBit);

        // 打印拥有的权限
        System.out.println(bits(ownBit));

    }

    public static void practice11(long num) {

        /* 以一个最高有效位为1的二进制数开始用有符号右移操作符对其进行右移，
         * 直至所有二进制位被移除为止，每移一位都要使用Integer.toBinaryString()显示结果
         *
         */
        long limit = num > 0 ? 0 : -1;
        int count = 0;

        while (num != limit) {
            count++;
            num >>= 1;
            System.out.println(Long.toBinaryString(num) + " => " + num);
        }

        System.out.println(count);
    }

    public static void practice12(long num) {

        // 以一个所有位都为1的二进制数字开始，先左移它，然后用无符号右移操作符对其进行右移
        // 直至所有二进制位被移除为止，每移一位都要使用Integer.toBinaryString()显示结果
        num <<= 1;
        System.out.println(Long.toBinaryString(num) + " => " + num);

        while (num != 0) {
            num >>>= 1;
            System.out.println(Long.toBinaryString(num) + " => " + num);
        }

    }

    public static void leftMove(int num) {
        for (int i = 0; i < 32; i++) {
            // 一直向左移动
            System.out.println(Integer.toBinaryString(num <<= 1) + " -> " + num);
        }
    }

    public static String practice13(long num) {
        StringBuilder stringBuilder = new StringBuilder(64);
        while (num != 0) {
            stringBuilder.append(num & 1);
            num >>>= 1;
        }

        return stringBuilder.reverse().toString();
    }

    /**
     * 删除一个权限
     */
    public static int removeEqualsBit(int beforeBit, int deductBit) {
        return beforeBit ^ (beforeBit & deductBit);
    }

    /**
     * 添加一个权限
     */
    public static int addUnequalsBit(int beforeBit, int toBeAddBit) {
        return beforeBit |= toBeAddBit;
    }

    /**
     * 判断用户是否包含某个权限
     */
    public static boolean isInclude(int ownBit, int validateBit) {
        return (ownBit & validateBit) > 0;
    }


    /**
     * 获取一个用户的所有权限
     */
    public static List<Integer> bits(int ownBit) {
        // << 2的n次幂
        List<Integer> bitList = new LinkedList<>();
        int currentBitValue = 1;
        do {
            if (isInclude(ownBit, currentBitValue)) {
                bitList.add(currentBitValue);
            }
        } while ((currentBitValue <<= 1) != Integer.MIN_VALUE);
        return bitList;
    }
// SQLOutput
}
